﻿using Microsoft.Extensions.Logging;
using MiniJob.Jobs;
using System.Diagnostics;
using System.Text.Json;

namespace MiniJob.Worker.Jobs;

/// <summary>
/// 广播文件清理执行器
/// </summary>
public class FileCleanupJob : BroadcastJob
{
    protected override Task<JobResult> DoWorkAsync(JobContext context, CancellationToken cancellationToken = default)
    {
        cancellationToken.ThrowIfCancellationRequested();

        Logger.LogInformation("using params {JobParams}", context.JobParams);

        if (context.JobParams.IsNullOrWhiteSpace())
        {
            return Task.FromResult(JobResult.ErrorMessage("job params is null."));
        }

        return Task.Factory.StartNew(() =>
        {
            int cleanNum = 0;
            var stopwatch = Stopwatch.StartNew();

            var cleanupParamsList = JsonSerializer.Deserialize<List<CleanupParams>>(context.JobParams)!;

            foreach (var param in cleanupParamsList)
            {
                Logger.LogInformation("Start to process {@Param}", param);

                if (param.FilePattern.IsNullOrEmpty() || param.DirPath.IsNullOrEmpty())
                {
                    Logger.LogWarning("skip due to invalid param {@Param}", param);
                    continue;
                }

                if (!Directory.Exists(param.DirPath))
                {
                    Logger.LogWarning("skip due to {DirPath} not exixts", param.DirPath);
                    continue;
                }

                var files = Directory.GetFiles(param.DirPath, param.FilePattern);
                Logger.LogInformation($"{param.FilePattern} pattern total file num: {files.Length}");

                foreach (var file in files)
                {
                    var fileInfo = new FileInfo(file);
                    if (fileInfo.LastWriteTime > DateTime.Now - param.RetentionTime)
                    {
                        Logger.LogInformation("{File} won't be deleted because it does not meet the time requirement", file);
                        continue;
                    }

                    try
                    {
                        fileInfo.Delete();
                        cleanNum++;
                        Logger.LogInformation("delete {File} successfully!", file);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex, "delete {File} failed!", file);
                    }
                }
            }

            stopwatch.Stop();
            return new JobResult(true, $"cost:{stopwatch.Elapsed}, clean:{cleanNum} file");
        });
    }
}
